/*
	Contains the winapi window message routing code

	Author: Aidan Goddard 22/7/14
*/

#include"Window.h"

/////////////////////////////////////////////////////////////
// message handler register function
void Snowstorm::Window::RegisterHandler(UINT handle, void(*handler)(Window*, WPARAM, LPARAM))
{
	// check handler is valid
	if(!handler)
	{
		return;
	}

	// add handler reference
	this->msg_handlers[handle] = handler;

	// finished
	return;
}

/////////////////////////////////////////////////////////////
// message loop control function
int Snowstorm::Window::MessageLoop()
{
	MSG msg;
	while(PeekMessage(&msg, NULL, 0, 0, TRUE))
	{
		if(msg.message == WM_QUIT)
            return 0;
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return 1;
}


/////////////////////////////////////////////////////////////
// single window message router
LRESULT CALLBACK Snowstorm::Window::SingleWindowRouter(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	// check if the swi object exists (it *should* do)
	if(Window::swi)
	{
		return Window::swi->InstanceMsgHandler(msg, wparam, lparam);
	}
	else
	{
		return DefWindowProc(hwnd, msg, wparam, lparam);
	}
}


/////////////////////////////////////////////////////////////
// multi window message router
LRESULT CALLBACK Snowstorm::Window::MsgRouter(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	// check if the Window with the associated hwnd exists (it *should* do)
	int count = (int)Window::hwnd_map.count(hwnd);
	if(count == 0)
	{
		// it does not exist.
		return DefWindowProc(hwnd, msg, wparam, lparam);
	}
	else
	{
		// it does exist
		Window *wnd = Window::hwnd_map[hwnd];

		// call the window's handler
		return wnd->InstanceMsgHandler(msg, wparam, lparam);
	}
}


/////////////////////////////////////////////////////////////
// instance message handler function
LRESULT CALLBACK Snowstorm::Window::InstanceMsgHandler(UINT msg, WPARAM wparam, LPARAM lparam)
{
	// check if msg has a handler installed
	int count = (int)this->msg_handlers.count(msg);
	if(count > 0)
	{
		// call the installed handler
		void(*msg_handler)(Window*, WPARAM, LPARAM) = msg_handlers[msg];
		msg_handler(this, wparam, lparam);
		return 0;
	}
	else
	{
		// call the default handler
		switch(msg)
		{
			case WM_CLOSE:
				break;

			case WM_QUIT:
				break;
			
			case WM_CREATE:
				break;

			case WM_SIZE:
				break;

			case WM_INPUT:
				this->HandleUserInput(wparam, lparam);
				return 0;
			
			default:
				return DefWindowProc(hwnd, msg, wparam, lparam);
				break;
		}
		return 0;
	}
}

